iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Software Development

燃燒大三的成果發表系列 第 12

燃燒大三的成果發表第十二天 - Generator

  • 分享至 

  • xImage
  •  

今天來到了介紹Generator(生成器),過去我們有介紹列表推導式,但其實dict、set也都可以用推導式的寫法,但是唯獨tuple很特別。

今天如果我們這樣寫(i for i in range(0, 11))把這串印出來,他就會是一個生成器<generator object <genexpr> at 0x102769270>,生成器有兩個特點

  1. 只能取得一次的值
  2. 函數裡面含有yield

    It looks like a normal function except that it contains yield expressions for producing a series of values usable in a for-loop or that can be retrieved one at a time with the next() function. - 「3.10.6 Python Documentation

我們馬上用程式驗證看看以上兩個特點:

a = (i for i in range(0, 11))
for i in (1, 2):
    for j in a:
        print(j)

我把上面生成器的範例取出資料的動作重複做兩次,也確實只能取出一次資料,那我們接著再試看看,宣告一個方法裡面加上yield

def gen():
    yield 123
    
print(gen())  # <generator object gen at 0x10278e270>

加上yield的方法也確實是生成器,但是卻不清楚yield做什麼的嗎? 從上面生成器的定義看起來感覺跟next()有點關係,那我們就用生成器搭配next()再試看看

def gen():
    yield 123
    yield 456
    yield 789
    
g = gen()
print(next(g))  # 123
print(next(g))  # 456
print(next(g))  # 789

可是我之前只介紹有next()卻沒有說他是幹嘛的嗎?

Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised. - 「3.10.6 Python Documentation

根據官方文件對next的描述,我們可以了解next()其實是幫助我們從生成器或者是迭代器中一直取出下一個資料,直到資料全部被取出。

那上面這個例子其實就可以很清楚的了解,yield能夠記住當下取得的部分,每呼叫一次next他會繼續往下取值。

最後分享一下我的心得,過去我在還沒有了解迭代器或者是生成器的時候,踩了滿多坑,也常常print出來是把迭代器或者是生成器物件印出來,卻發現沒有值,在了解之後可能還不是到很厲害,但是起碼你對這個概念有稍微認識,不至於到很陌生,通常對於越陌生的東西,我們就會感到越害怕,所以雖然我介紹的東西
可能不實用,但是認識它,你絕對不會有損失。

明天我要接著來分享一下字串格式化


上一篇
燃燒大三的成果發表第十一天 - Iterator
下一篇
燃燒大三的成果發表第十三天 - 字串格式化
系列文
燃燒大三的成果發表30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言